package cn.dansj.common.utils.spring.context.condition;

import cn.dansj.common.utils.lang.NotNull;
import cn.dansj.common.utils.spring.context.ApplicationContextProvider;
import cn.dansj.common.utils.transfer.Verification;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.context.annotation.ConfigurationCondition;
import org.springframework.core.annotation.Order;
import org.springframework.core.type.AnnotatedTypeMetadata;

import java.util.Map;

@Order
class OnBeanCondition implements ConfigurationCondition {
    @Override
    public boolean matches(@NotNull ConditionContext context, @NotNull AnnotatedTypeMetadata metadata) {
        Map<String, Object> attributes = metadata.getAnnotationAttributes(ConditionalOnBean.class.getName(), false);
        ListableBeanFactory beanFactory = context.getBeanFactory();
        // 需要基于beanFactory判断，beanFactory为空直接返回false
        if (beanFactory == null || attributes == null) return false;
        String[] name = (String[]) attributes.get("name");
        Class<?>[] value = (Class<?>[]) attributes.get("value");
        MatchType matchType = (MatchType) attributes.get("matchType");
        if (MatchType.Match.equals(matchType)) {
            return Verification.checkAllNull(name, value) ? !ApplicationContextProvider.hasBean(beanFactory, ConditionalUtils.extractConfigClass(metadata))
                    : ApplicationContextProvider.hasBean(beanFactory, name) && ApplicationContextProvider.hasBean(beanFactory, value);
        } else {
            return Verification.checkAllNull(name, value) ? !ApplicationContextProvider.hasBean(beanFactory, ConditionalUtils.extractConfigClass(metadata))
                    : !ApplicationContextProvider.hasAnyBean(beanFactory, name) && !ApplicationContextProvider.hasAnyBean(beanFactory, value);
        }
    }

    @Override
    @NotNull
    public ConfigurationPhase getConfigurationPhase() {
        return ConfigurationPhase.REGISTER_BEAN;
    }
}
